﻿using Furion.Logging.Extensions;
using Furion.Templates;
using Furion.FriendlyException;
using AngleSharp.Dom;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System.Text.RegularExpressions;
using Admin.NET.Application.Util.Extension;
using Radius.NET.Interface.Kingdee.Entity;

namespace Radius.NET.Interface.Kingdee.Service
{
    /// <summary>
    /// 采购订单服务
    /// </summary>
    [ApiDescriptionSettings(KingdeeConfigConst.GroupName, Order = 004)]
    public class PuOrdersService : IDynamicApiController, ITransient
    {
        private readonly SqlSugarRepository<Radius.NET.Interface.Entity.PuOrders> PuOrdersRespository;
        private readonly SqlSugarRepository<InventoryEvidence> evidenveRespository;
        private readonly KingdeeUtil _kingdeeUtil;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_PuOrdersRespository"></param>
        /// <param name="kingdeeUtil"></param>
        /// <param name="_evidenveRespository"></param>
        public PuOrdersService(
            SqlSugarRepository<Radius.NET.Interface.Entity.PuOrders> _PuOrdersRespository,
            KingdeeUtil kingdeeUtil,
            SqlSugarRepository<InventoryEvidence> _evidenveRespository)
        {
            PuOrdersRespository = _PuOrdersRespository;
            evidenveRespository = _evidenveRespository;
            _kingdeeUtil = kingdeeUtil;
        }

        #region 同步采购订单
        /// <summary>
        /// 同步采购订单
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="Bdate"></param>
        /// <param name="fbillNo"></param>
        /// <returns></returns>
        [HttpPost("/kindeeIcloud/puorders/{cid}"), AllowAnonymous]
        public async Task<object> GetPuOrdersList(int cid, string Bdate, string fbillNo)
        {
            //var apiConfig = await apiConfigListService.GetApiConfigByCode("kindeeIcloud_puorders");
            //if (apiConfig.Status != StatusEnum.Enable)
            //    throw Oops.Oh("接口已禁用！").StatusCode(900);
            var KingdeeUtil = await _kingdeeUtil.GetClient("kindeeIcloud_puorders");
            if (string.IsNullOrEmpty(Bdate))
                Bdate = DateTime.Now.ToString();

            //KingdeeConfig kingdeeConfig = await sysConfigService.GetKindgdeeIcloudConfig(apiConfig.IsMaster);
            List<Radius.NET.Interface.Entity.PuOrders> PuOrders_List = new();
            List<string> CGNo = new();
            string filterString = $"FPurchaseOrgId.FNumber = '{KingdeeConfigConst.ORGID}' and FDate >= '{Bdate}' and FDocumentStatus='C' and FCloseStatus='A'";
            if (!string.IsNullOrEmpty(fbillNo))
            {
                filterString += $" and FBillNo = '{fbillNo}'";
            }
            var list = KingdeeUtil.Query<PUR_PurchaseOrderDto>(KingdeeFormConst.PUR_PurchaseOrder, filterString);

            foreach (var item in list)
            {
                string orderId = item.FBillNo;
                if (!await PuOrdersRespository.IsAnyAsync(x => x.OrderID.Equals(orderId) && x._cid.Equals(cid)))
                {
                    var childObj = new PuOrderDetail()
                    {
                        OrderID = item.FBillNo,
                        Inventory_ID = item.FMaterialId_FNumber,
                        NOID = item.FPOOrderEntry_FSEQ,
                        Price = item.FTaxPrice,
                        Order_Qty = item.FQty,
                        Order_Amount = item.FEntryAmount,
                        FKNOID = item.FPOOrderEntry_FEntryID,
                        _cid = cid
                    };

                    if (PuOrders_List.FirstOrDefault(x => x.OrderID.Equals(orderId)) is not null)
                    {
                        PuOrders_List.FirstOrDefault(x => x.OrderID.Equals(orderId))?.FG_PuOrderDetail.Add(childObj);
                    }
                    else
                    {
                        PuOrders_List.Add(new Radius.NET.Interface.Entity.PuOrders
                        {

                            #region 拼接主表字段
                            OrderID = item.FBillNo,
                            Maker = item.FCreatorId,
                            OrderDate = item.FDate,
                            ContactNum = item.FSupplierIdFNumber,
                            OrderMan = item.FPurchaserId,
                            FInterID = item.FID,
                            Posted = 0,
                            _cid = cid,
                            #endregion

                            #region 拼接采购订单子表字段
                            FG_PuOrderDetail = new List<PuOrderDetail>() { childObj }
                            #endregion

                        });
                    }
                }
            }
            if (PuOrders_List.Count == 0)
                throw Oops.Bah("无可同步的数据或者已存在！");
            //插入BS数据库
            return await PuOrdersRespository.AsInsertable(PuOrders_List.ToArray())
                //按导航属性插入子表
                .AddSubList(x => x.FG_PuOrderDetail).ExecuteCommandAsync();
        }
        #endregion

        #region 同步收料通知单到IQC单据
        /// <summary>
        /// 同步收料通知单到IQC单据
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="Bdate"></param>
        /// <param name="fbillNo"></param>
        /// <returns></returns>
        [HttpPost("/kindeeIcloud/Sltzd/{cid}"), AllowAnonymous]
        public async Task<object> GetSltzdToIqc(int cid, string Bdate, string fbillNo)
        {
            var KingdeeUtil = await _kingdeeUtil.GetClient("kindeeIcloud_sltzd");
            if (string.IsNullOrEmpty(Bdate))
                Bdate = DateTime.Now.ToString();

            List<InventoryEvidence> IQC_List = new();
            List<string> CGNo = new();
            string filterString = $"FStockOrgId.FNumber = '{KingdeeConfigConst.ORGID}' and FDate >= '{Bdate}' and FDocumentStatus='C' ";
            if (!string.IsNullOrEmpty(fbillNo))
            {
                filterString += $" and FBillNo = '{fbillNo}'";
            }
            var list = KingdeeUtil.Query<PUR_ReceiveBillDto>(KingdeeFormConst.PUR_ReceiveBill,filterString);

            foreach (var item in list)
            {
                string orderId = item.FBillNo;

                if (!await evidenveRespository.IsAnyAsync(x => x.Evidence_Number.Equals(orderId) && x._cid.Equals(cid)))
                {
                    string FMaterialModel = item.F_asdg_AssistantFDataValue;
                    double utwt = string.IsNullOrEmpty(FMaterialModel.Trim()) ? 1 : Convert.ToDouble(Regex.Replace(FMaterialModel, @"[^0-9]+", ""));

                    var childObj = new InventoryEvidenceDetail()
                    {
                        Evidence_Number = item.FBillNo,
                        Inventory_ID = item.FMaterialId_FNumber,
                        NOID = item.FDetailEntity_FSEQ,
                        Price = item.FTaxPrice,
                        OrderQty = item.FPOQTY,
                        NPKG = item.FExtAuxUnitQty,
                        LogoID = item.FAuxPropId_FF100001_FNumber,
                        QcVerify = -1,
                        Check_Result = "全收",
                        Unit_weight = utwt,
                        ProjectBatch = FMaterialModel,//item.ItemIndexOf(PUR_ReceiveBill_FieldKeys, "FLot").ParseToString(),
                        //MakeBeginDate = item.ItemIndexOf(PUR_ReceiveBill_FieldKeys, "FProduceDate").ParseToString().ParseToDateTime(),
                        //EndDate = item.ItemIndexOf(PUR_ReceiveBill_FieldKeys, "FExpiryDate").ParseToString().ParseToDateTime(),
                        Qty = item.FActlandQty,
                        Check_Qty = item.FReceiveQty,
                        Amount = item.FAmount,
                        //CF01 = item.ItemIndexOf(PUR_ReceiveBill_FieldKeys, "FSupplierLot").ParseToString(),
                        _cid = cid
                    };

                    if (IQC_List.FirstOrDefault(x => x.Evidence_Number.Equals(orderId)) is not null)
                    {
                        IQC_List.FirstOrDefault(x => x.Evidence_Number.Equals(orderId))?.FG_InvDetail.Add(childObj);
                    }
                    else
                    {
                        IQC_List.Add(new InventoryEvidence
                        {
                            #region 拼接主表字段
                            Evidence_Number = item.FBillNo,
                            Maker = item.FCreatorIdFName,
                            Date = item.FDate,
                            ContactNum = item.FSupplierIdFNumber,
                            OrderID = item.FOrderBillNo,
                            Stock_ID = "IQC",
                            Posted = 0,
                            Closed = 0,
                            _cid = cid,
                            Type = 30,
                            #endregion

                            #region 拼接采购订单子表字段
                            FG_InvDetail = new List<InventoryEvidenceDetail>() {
                                childObj
                            }
                            #endregion
                        });
                    }
                }
            }
            if (IQC_List.Count == 0)
                throw Oops.Bah("无可同步的数据或者已存在！");
            var deleteList = new List<InventoryEvidence>();
            foreach (var item in IQC_List)
            {
                //根据收料通知单查询检验单数据
                var QcList = GetQcBySltzd(KingdeeUtil, item.Evidence_Number);
                if (QcList.Count > 0)
                {
                    bool isRemove = false;
                    foreach (var detailItem in item.FG_InvDetail)
                    {
                        if (detailItem.Check_Qty > 0)
                        {
                            var qc = QcList.Find(x => x.FMaterialFNumber == detailItem.Inventory_ID);
                            detailItem.MakeBeginDate = qc?.FProduceDate;
                            detailItem.EndDate = qc?.FExpiryDate;
                            detailItem.ProjectBatch = qc.FLot + "/" + detailItem.ProjectBatch;
                            detailItem.SupBatch = qc?.FMemo;
                            detailItem.CF03 = qc?.F_asdg_Date1.ToString("G");
                        }
                        else
                        {
                            isRemove = true;
                            break;
                        }
                    }
                    if (isRemove)
                    {
                        deleteList.Add(item);
                    }
                }
                else
                {
                    deleteList.Add(item);
                }
            }

            foreach (var item in deleteList)
            {
                IQC_List.Remove(item);
            }

            if (IQC_List.Count == 0)
                throw Oops.Bah("无可同步的数据或收料通知单材料未全部检验合格");
            //插入BS数据库
            return await evidenveRespository.AsInsertable(IQC_List.ToArray())
                //按导航属性插入子表
                .AddSubList(x => x.FG_InvDetail).ExecuteCommandAsync();
        }
        #endregion

        #region IQC保存生成收料通知单
        /// <summary>
        /// IQC保存生成收料通知单
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="EviNum"></param>
        /// <returns></returns>
        [HttpPost("/kindeeIcloud/puorders/tosltzd/{cid}"), AllowAnonymous]
        public async Task<object> IQCSaveToSLD(int cid, string EviNum)
        {
            //var apiConfig = await apiConfigListService.GetApiConfigByCode("kindeeIcloud_issuePlan_tosltzd");
            //if (apiConfig.Status != StatusEnum.Enable)
            //    throw Oops.Oh("接口已禁用！").StatusCode(900);
            var KingdeeUtil = await _kingdeeUtil.GetClient("kindeeIcloud_issuePlan_tosltzd");
            if (string.IsNullOrEmpty(EviNum))
                throw Oops.Oh(errorMessage: "单号不能为空！");

            //KingdeeConfig = await sysConfigService.GetKindgdeeIcloudConfig(apiConfig.IsMaster);

            //获取IQC入库单数据
            var iqcrkItem = await evidenveRespository.AsQueryable()
                .Includes(x => x.FG_InvDetail, z => z.FG_Inventory)
                .Where(x => x.Evidence_Number.Equals(EviNum) && x._cid == cid)
                .FirstAsync();

            if (iqcrkItem is null)
                throw Oops.Bah("IQC入库单记录不存在！");

            if (string.IsNullOrEmpty(iqcrkItem.OrderID))
                throw Oops.Bah("IQC入库单未关联采购订单！");

            JsonConvert.SerializeObject(iqcrkItem).LogInformation();

            List<PUR_PurchaseOrderDto> receiveBillDto = QueryCgdByNumber(KingdeeUtil, iqcrkItem.OrderID);
            var data = new PUR_ReceiveBill().BuildData(iqcrkItem, receiveBillDto);
            Log.Information($"写入云星空采购订单JSON：{JsonConvert.SerializeObject(data)}");
            return KingdeeUtil.Save("PUR_ReceiveBill", data);
        }
        #endregion

        #region 材料入库单保存生成采购入库单
        /// <summary>
        /// 材料入库单保存生成采购入库单
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="EviNum"></param>
        /// <returns></returns>
        [HttpPost("/kindeeIcloud/puorders/tocgrk/{cid}"), AllowAnonymous]
        public async Task<object> MriSaveToSLD(int cid, string EviNum)
        {
            var KingdeeUtil = await _kingdeeUtil.GetClient("kindeeIcloud_issuePlan_tocgrk");
            if (string.IsNullOrEmpty(EviNum))
                throw Oops.Bah(errorMessage: "单号不能为空！");

            //获取IQC入库单数据
            var iqcrkItem = await evidenveRespository.AsQueryable()
                .Includes(x => x.FG_InvDetail, z => z.FG_Inventory)
                .Where(x => x.Evidence_Number.Equals(EviNum) && x._cid == cid)
                .FirstAsync();

            if (iqcrkItem is null)
                throw Oops.Bah("IQC入库单记录不存在！");

            if (string.IsNullOrEmpty(iqcrkItem.OrderID))
                throw Oops.Bah("IQC入库单未关联采购订单！");

            JsonConvert.SerializeObject(iqcrkItem).LogInformation();

            List<PUR_ReceiveBillDto> receiveBillDto = QuerySLTZDByNumber(KingdeeUtil, iqcrkItem.IQCNo);
            var data = new STK_InStock().BuildData(iqcrkItem, receiveBillDto);

            TP.Wrapper("云星空采购入库保存", "材料入库单保存生成采购入库单",
            $"##本地json## {JsonConvert.SerializeObject(iqcrkItem)}",
            $"##云星空json## {JsonConvert.SerializeObject(data)}").LogInformation();

            return KingdeeUtil.Save("STK_InStock", data);
        }
        #endregion

        #region 根据采购单号查询金蝶采购订单
        [NonAction]
        public List<PUR_PurchaseOrderDto> QueryCgdByNumber(KingdeeUtil kingdeeUtil, string number)
        {
            var list = kingdeeUtil.Query<PUR_PurchaseOrderDto>(KingdeeFormConst.PUR_PurchaseOrder, $"FBillNo = '{number}'");
            if (list.Count == 0)
                throw Oops.Bah("金蝶采购订单记录不存在！");

            return list;
        }
        #endregion

        #region 根据IQC单号查询金蝶收料通知单
        /// <summary>
        /// 根据IQC单号查询金蝶收料通知单
        /// </summary>
        /// <param name="kingdeeUtil"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        [NonAction]
        public List<PUR_ReceiveBillDto> QuerySLTZDByNumber(KingdeeUtil kingdeeUtil, string number)
        {
            var list = kingdeeUtil.Query<PUR_ReceiveBillDto>(KingdeeFormConst.PUR_ReceiveBill, $"FBillNo = '{number}'");
            if (list.Count == 0)
                throw Oops.Bah("金蝶收料通知单记录不存在！");
            return list;
        }
        #endregion

        #region 材料退货单保存成功生成采购退料单
        /// <summary>
        /// 材料退货单保存成功生成采购退料单
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="EviNum"></param>
        /// <returns></returns>
        [HttpPost("/kindeeIcloud/puorders/tocgtld/{cid}"), AllowAnonymous]
        public async Task<object> MrvSaveToPUR_MRB(int cid, string EviNum)
        {
            var KingdeeUtil = await _kingdeeUtil.GetClient("kindeeIcloud_puorders_tocgtld");
            if (string.IsNullOrEmpty(EviNum))
                throw Oops.Bah(errorMessage: "单号不能为空！");

            var mrvItem = await evidenveRespository.AsQueryable()
                .Includes(x => x.FG_InvDetail, z => z.FG_Inventory)
                .Where(x => x.Evidence_Number.Equals(EviNum) && x._cid == cid)
                .FirstAsync();
            List<PUR_PurchaseOrderDto> receiveBillDto = QueryCgdByNumber(KingdeeUtil, mrvItem.IQCNo);
            var data = new PUR_MRB().BuildData(mrvItem, receiveBillDto);


            TP.Wrapper("云星空采购退料保存", "材料退货单保存生成采购退料单",
            $"##本地json## {JsonConvert.SerializeObject(mrvItem)}",
            $"##云星空json## {JsonConvert.SerializeObject(data)}").LogInformation();

            return KingdeeUtil.Save("PUR_MRB", data);
        }
        #endregion

        #region 根据收料通知单获取检验单信息
        private List<QM_InspectBillDto> GetQcBySltzd(KingdeeUtil kingdeeUtil, string number)
        {
            var list = kingdeeUtil.Query<QM_InspectBillDto>(KingdeeFormConst.QM_InspectBill, $"FSrcBillNo = '{number}' and FInspectResult = 1");
            JSON.Serialize(list, this).LogInformation();
            return list;
        }
        #endregion
    }
}
